import threading
import re
from typing import Dict, Any, List
from contextlib import contextmanager
from infrastructure.db_pool_manager import DatabasePoolManager

class FieldMapDao:
    def __init__(self, config_path: str = 'conf/dao_config.toml'):
        """
        初始化FieldMapDao
        
        Args:
            config_path: 配置文件路径
        """
        self.db_manager = DatabasePoolManager(config_path)
        self.config = self.db_manager.get_config()
        self._lock = threading.Lock()
    @property
    def table_name(self) -> str:
        """获取表名"""
        return self.config['table']['field_map']
    @contextmanager
    def get_connection(self):
        """获取数据库连接的上下文管理器"""
        connection = self.db_manager.get_connection()
        try:
            yield connection
        except Exception as e:
            connection.rollback()
            raise e
        finally:
            connection.close()
    def reload_config(self):
        """重新加载配置文件"""
        with self._lock:
            self.db_manager.reload_config()
            self.config = self.db_manager.get_config()
    def get_ai_field_name(self, db_field_name: str) -> str:
        """
        根据数据库字段名获取AI识别字段名
        
        Args:
            db_field_name: 数据库字段名
        
        Returns:
            对应的AI字段名，如果未找到则返回原字段名
        """
        try:
            with self.get_connection() as connection:
                with connection.cursor() as cursor:
                    sql = f"SELECT ai_field_name FROM {self.table_name} WHERE db_field_name = %s"
                    cursor.execute(sql, (db_field_name,))
                    result = cursor.fetchone()
                    
                    if result and result['ai_field_name']:
                        return result['ai_field_name']
                    else:
                        # 如果未找到映射，返回原字段名
                        return db_field_name
                        
        except Exception as e:
            raise Exception(f"❌ 获取AI字段名失败: {e}")
    def get_db_field_name(self, ai_field_name: str) -> str:
        """
        根据AI字段名获取数据库字段名
        
        Args:
            ai_field_name: AI识别的字段名
        
        Returns:
            对应的数据库字段名，如果未找到则返回None
        """
        try:
            with self.get_connection() as connection:
                with connection.cursor() as cursor:
                    sql = f"SELECT db_field_name FROM {self.table_name} WHERE ai_field_name = %s"
                    cursor.execute(sql, (ai_field_name,))
                    result = cursor.fetchone()
                    
                    if result and result['db_field_name']:
                        return result['db_field_name']
                    else:
                        # 如果未找到映射，返回None（与email_processor.py中的使用方式一致）
                        return None
                        
        except Exception as e:
            raise Exception(f"❌ 获取数据库字段名失败: {e}")
    def validate_data(self, email_data: Dict[str, Any]) -> Dict[str, Any]:
        """根据数据库中的正则表达式验证和处理数据"""
        validated_data = {}
        connection = None
        
        try:
            with self.get_connection() as connection:
                for ai_field_name, value in email_data.items():
                    # 从数据库查询该AI字段的验证规则
                    with connection.cursor() as cursor:
                        sql = f"SELECT validation_rule FROM {self.table_name} WHERE ai_field_name = %s"
                        cursor.execute(sql, (ai_field_name,))
                        result = cursor.fetchone()
                        
                        # 如果找不到字段配置，直接使用原值
                        if result is None:
                            validated_data[ai_field_name] = value
                            continue

                        # 修复：正确处理result的打印
                        validation_rule = result['validation_rule'] if result['validation_rule'] else None

                        # 如果值为空，直接使用原值
                        if value is None or value == '':
                            validated_data[ai_field_name] = value
                            continue
                        
                        # 如果没有验证规则，直接使用原值
                        if validation_rule is None or validation_rule == '':
                            validated_data[ai_field_name] = value
                            continue
                        
                        # 确保值是字符串类型进行正则验证
                        str_value = str(value)
                        
                        # 执行正则表达式验证
                        try:
                            if not re.match(validation_rule, str_value):
                                raise ValueError(f"字段 '{ai_field_name}' 的值 '{str_value}' 不符合正则表达式 '{validation_rule}'")
                            validated_data[ai_field_name] = value
                        except re.error as regex_error:
                            raise ValueError(f"字段 '{ai_field_name}' 的正则表达式 '{validation_rule}' 格式错误: {regex_error}")
                
                return validated_data
            
        except Exception as e:
            raise Exception(f"❌ 数据验证失败: {e}")
        finally:
            if connection:
                connection.close()
    # 在FieldMapDao中添加批量转换方法
    def convert_records_batch(self, records: List[Dict[str, Any]]) -> List[Dict[str, Any]]:
        """批量转换数据库记录为AI字段"""
        if not records:
            return []
        
        # 一次性获取所有需要的字段映射
        db_fields = set()
        for record in records:
            db_fields.update(record.keys())
        
        # 批量获取映射关系（可以考虑缓存）
        field_mappings = {}
        for db_field in db_fields:
            field_mappings[db_field] = self.get_ai_field_name(db_field)
        
        # 批量转换
        converted_records = []
        for record in records:
            converted_record = {}
            for db_field, value in record.items():
                ai_field = field_mappings[db_field]
                converted_record[ai_field] = value
            converted_records.append(converted_record)
        
        return converted_records

    def get_all(self):
        try:
            with self.get_connection() as connection:
                with connection.cursor() as cursor:
                    sql = f"SELECT ai_field_name, db_field_name FROM {self.table_name}"
                    cursor.execute(sql)
                    results = cursor.fetchall()
            return results
        except Exception as e:
            raise Exception(f"❌ 获取所有字段映射关系失败: {e}")